import { unified } from "unified" import parse from 'remark-parse' import { visit } from 'unist-util-visit' const Regex = { Line: /\r\n|\n/g, Tags: /#([dct])\s(\S+)/g, Subtitle: /^\[(\d{2}:\d{2}\.\d{3})(?:-(\d{2}:\d{2}\.\d{3}))?\]\s*(.*)/, Active: /\[(.*?)\]\((.*?)\s(\-.*?)\)/ } const Type = { P: 'paragraph', Tag: 'tag', Subtitle: 'subtitle', Active: 'active', Content: 'content' } const processer = unified() .use(parse) .use(() => (tree: any) => { visit(tree, 'text', (_node: any, _index: any, _parent: any) => { if (Type.P !== _parent.type) { return } // get value const str = _node.value // reset node _node.type = Type.P _node.value = undefined _node.children = [] // split const sg = str.split(Regex.Line).filter((it: any) => it) sg.forEach((s: any) => { if (Regex.Tags.test(s)) { const tag = s.substring(0, 2) const value = s.substring(3) const custom = { type: Type.Tag, properties: { tag: tag }, value: value } _node.children.push(custom) } else if (Regex.Subtitle.test(s)) { const matches = s.match(Regex.Subtitle) const st = matches[1] const et = matches[2] const value = matches[3] let type = Type.Subtitle let title: any let options: any let active: any if (Regex.Active.test(value)) { type = Type.Active const m = value.match(Regex.Active) title = m[1] options = m[2] active = m[3] } const custom = { type: type, properties: { st: st, et: et, title: title, options: options, active: active }, value: Type.Subtitle === type? value : '' } _node.children.push(custom) } }) }) return tree }) const Parser = { ast: (text?:string) => { const _ast = processer.runSync(processer.parse(text)) console.log('ast =>', _ast) return _ast; } } export default Parser